package com.cbarmstrong.Finance;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYSplineRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.TimeSeriesDataItem;
import org.jfree.data.xy.XYDataset;

public class TradeSet implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 504104119605629101L;
	private Vector<SpreadTrade> openSpreadTrades, closedSpreadTrades;
	private double profit=0;
	private Vector<Double> profitVect=new Vector<Double>();
	private int wins=0,losses=0;
	private String lastTrade="";
	
	public TradeSet(){
		openSpreadTrades=new Vector<SpreadTrade>();
		closedSpreadTrades=new Vector<SpreadTrade>();
	}

	public double pct(boolean win){
		int wins=0,losses=0;
		if(closedSpreadTrades.size()==0){ return -1.0; }
		for(int i=0;i<closedSpreadTrades.size();i++){
			if(closedSpreadTrades.get(i).getProfit()>0){ wins++; }
			else{ losses++; }
		}
		if(win){ return (double) wins*100/closedSpreadTrades.size(); }
		else{ return (double) losses*100/closedSpreadTrades.size(); }
	}
	
	public SpreadTrade[] getClosedTrades(){
		return closedSpreadTrades.toArray(new SpreadTrade[1]);
	}
	
	public SpreadTrade[] getOpenTrades(){
		return openSpreadTrades.toArray(new SpreadTrade[1]);
	}
	
	public int getPosition(){
		int position=0;
		for(int i=0;i<openSpreadTrades.size();i++){
			position+=openSpreadTrades.get(i).getPosition();
		}
		return position;
	}
	
	public boolean currentlyOut(){
		return getPosition()==0;
	}

	public boolean currentlyLong(){ 
		return getPosition()>0;
	}

	public boolean currentlyShort(){ 
		return getPosition()<0;
	}

	public int closedSpreadTrades(){
		return closedSpreadTrades.size();
	}

	public void openTrade(Date d, int position, double price, double spread){
		openSpreadTrades.add(new SpreadTrade(d,price,position, spread));
		lastTrade="Opened "+position+" position on "+new SimpleDateFormat("dd/MM/yyyy").format(d);
		Data.getLogger().finest(lastTrade);
	}
	
	public String getLastTrade(){ return lastTrade; }
	
	public void closeTrade(Date d, double price){
		openSpreadTrades.get(0).close(d, price);
		if(openSpreadTrades.get(0).getProfit()>0){ wins++; } else { losses++; }
		profit+=openSpreadTrades.get(0).getProfit();
		profitVect.add(profit);
		closedSpreadTrades.add(openSpreadTrades.get(0));
		openSpreadTrades.remove(0);
		lastTrade="Closed position on "+new SimpleDateFormat("dd/MM/yyyy").format(d);
		Data.getLogger().finest(lastTrade);
	}
	
	public void makePicture(int width, int height, String fileName){
		JFreeChart chart = ChartFactory.createTimeSeriesChart("Chart", "", "", genProfitDataset("Profit"), true, false, false);
		try {
			File file=new File(fileName+".jpg");
			ChartUtilities.saveChartAsJPEG(file, chart, width, height);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void writePicture(int width, int height, OutputStream out){
		JFreeChart chart = ChartFactory.createTimeSeriesChart("Chart", "", "", genProfitDataset("Profit"), true, false, false);
		XYPlot plot=chart.getXYPlot();
		plot.setRenderer(new XYSplineRenderer(50));
		try {
			ChartUtilities.writeChartAsJPEG(out, chart, width, height);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private XYDataset genProfitDataset(String title){
		TimeSeriesCollection tsc = new TimeSeriesCollection();
		TimeSeries ts = new TimeSeries(title);
		for(int i=0;i<closedSpreadTrades.size();i++){
			ts.add(new TimeSeriesDataItem(new Day(closedSpreadTrades.get(i).getCloseDate()), profitVect.get(i)));
		}
		tsc.addSeries(ts);
		return tsc;
	}
	
	@SuppressWarnings("unused")
	private XYDataset genPositionDataset(String title){
		TimeSeriesCollection tsc = new TimeSeriesCollection();
		TimeSeries ts = new TimeSeries(title);
		int pos=0;
		for(int i=0;i<openSpreadTrades.size();i++){
			pos+=closedSpreadTrades.get(i).getPosition();
			ts.add(new TimeSeriesDataItem(new Day(closedSpreadTrades.get(i).getCloseDate()), pos));
		}
		tsc.addSeries(ts);
		return tsc;
	}

	public double getProfit(){
		return profit;
	}

	public Vector<Double> getProfitVect(){
		return profitVect;
	}

	public double pointsPerTrade(){
		if(wins+losses==0){ return 0; }
		return (double) profit/(wins+losses);
	}

	public Double stdDevPct() {
		if(getProfit()==0){ return -1.0; }
		return Data.getStDev(profitVect)*100/getProfit();
	}
	
	public Double stdDev(){
		if(getProfit()==0){ return -1.0; }
		return Data.getStDev(profitVect);
	}

	public int tradeCount() {
		return closedSpreadTrades.size();
	}

}
